﻿namespace Sustainalytics.ESGRatings.Tasks.Models

{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text.RegularExpressions;

    public class ReportLine
    {
        private static readonly Regex WordSplittingPattern = new Regex("(?<! )([A-Z])", RegexOptions.Compiled);

        public enum ScoresHeading
        {
            CompanyScore, 
            EnvironmentScore, 
            SocialScore, 
            GovernanceScore, 
            PreparednessScore, 
            DisclosureScore, 
            QuantitativeScore, 
            QualitativeScore, 
            AverageOfGroup, 
            RankWithinGroup, 
            PercentileRankWithinGroup, 
            RankWithinGroupEnvironment,
            RankWithinGroupSocial,
            RankWithinGroupGovernance,
            PercentileWithinGroupEnvironment,
            PercentileWithinGroupSocial,
            PercentileWithinGroupGovernance, 
            MaxWithinGroupPreparedeness,
            MaxWithinGroupDisclosure,
            MaxWithinGroupQuantitative,
            MaxWithinGroupQualitative
        }

        private static string GetScoresHeadingFormatted(ScoresHeading scoresHeading)
        {
            var scoresHeadingFormatted = WordSplittingPattern.Replace(scoresHeading.ToString(), " $1").TrimStart();// split the string into words by inserting a blank space in front of any capital letter

            return scoresHeading < ScoresHeading.RankWithinGroupEnvironment ? scoresHeadingFormatted
                                                                            : scoresHeadingFormatted.Insert(scoresHeadingFormatted.LastIndexOf(' '), " -");
        }

        static public ReportLine Header(IEnumerable<string> indicatorsName)
        {
            return new ReportLine
            {
                CapitalIQID = "Capital IQ ID",
                CompanyName = "Company name",
                PeerGroupName = "Peer group",
                IndustryGroupName = "Industry group",
                TemplateType = "Template type",
                CompanyType = "Company type",
                IndicatorsValue = indicatorsName.ToList() ?? new List<string>()
            };
        }

        static public ReportLine HeaderScores()
        {
            return new ReportLine()
            {
                CapitalIQID = "Capital IQ ID",
                CompanyName = "Company name",
                PeerGroupName = "Peer group",
                IndustryGroupName = "Industry group",
                TemplateType = "Template type",
                CompanyType = "Company type",
                IndicatorsValue = Enum.GetValues(typeof(ScoresHeading)).Cast<ScoresHeading>().Select(GetScoresHeadingFormatted).ToList()
            };
        }    

        public string CapitalIQID { get; set; }
        public string CompanyName { get; set; }
        public string PeerGroupName{ get; set; }
        public string IndustryGroupName { get; set; }
        public string TemplateType { get; set; }
        public string CompanyType { get; set; }
        public List<string> IndicatorsValue { get; set; }

        private bool Equals(ReportLine other)
        {
            return string.Equals(this.CapitalIQID, other.CapitalIQID) && string.Equals(this.CompanyName, other.CompanyName) && string.Equals(this.PeerGroupName, other.PeerGroupName) && string.Equals(this.IndustryGroupName, other.IndustryGroupName) && string.Equals(this.TemplateType, other.TemplateType) && string.Equals(this.CompanyType, other.CompanyType) && this.IndicatorsValue.SequenceEqual(other.IndicatorsValue);
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != this.GetType()) return false;
            return this.Equals((ReportLine) obj);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                int hashCode = this.CapitalIQID.GetHashCode();
                hashCode = (hashCode*397) ^ this.CompanyName.GetHashCode();
                hashCode = (hashCode*397) ^ this.PeerGroupName.GetHashCode();
                hashCode = (hashCode*397) ^ this.IndustryGroupName.GetHashCode();
                hashCode = (hashCode*397) ^ this.TemplateType.GetHashCode();
                hashCode = (hashCode*397) ^ this.CompanyType.GetHashCode();
                hashCode = (hashCode*397) ^ this.IndicatorsValue.GetHashCode();
                return hashCode;
            }
        }
    }

}
